package org.i1510.gen.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.i1510.common.service.impl.BaseServiceImpl;
import org.i1510.gen.bean.ConfigBean;
import org.i1510.gen.exception.BaseException;
import org.i1510.gen.po.ColumnInfo;
import org.i1510.gen.po.TableInfo;
import org.i1510.gen.service.IGenService;
import org.i1510.gen.utils.GenDateUtils;
import org.i1510.gen.utils.GenStringUtils;
import org.i1510.gen.utils.GenUtils;
import org.i1510.gen.utils.VelocityInitializer;
import org.springframework.stereotype.Service;

@Service("iGenService")
public class GenServiceImpl extends BaseServiceImpl implements IGenService {
	/**
	 * 生成代码
	 * 
	 * @param tableName
	 *            表名称
	 * @return 数据
	 */
	@Override
	public byte[] generatorCode(String tableName,ConfigBean configBean) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);
		// 查询表信息
		Map map = new HashMap();
		map.put("tableName", tableName);
		List tableList = this
				.queryForListBySql("genSql.selectTableByName", map);

		// 查询列信息
		List columnsList = this.queryForListBySql(
				"genSql.selectTableColumnsByName", map);
		if (tableList.size() == 1 && columnsList.size() > 0) {
			Map tb = (Map) tableList.get(0);
			TableInfo table = new TableInfo();
			table.setTableName(tb.get("tableName").toString());
			if (null != tb.get("tableComment")) {
				table.setTableComment(tb.get("tableComment").toString());
			} else {
				table.setTableComment("");
			}
			if (null != tb.get("createTime")) {
				table.setCreateTime(GenDateUtils.dateTime(
						"yyyy-MM-dd HH:mm:ss", tb.get("createTime").toString()));
			} else {
				table.setCreateTime(GenDateUtils.getNowDate());
			}
			if (null != tb.get("updateTime")) {
				table.setUpdateTime(GenDateUtils.dateTime(
						"yyyy-MM-dd HH:mm:ss", tb.get("updateTime").toString()));
			} else {
				table.setUpdateTime(GenDateUtils.getNowDate());
			}

			// 列
			List<ColumnInfo> columns = new ArrayList<ColumnInfo>();
			for (int i = 0; i < columnsList.size(); i++) {
				Map column = (Map) columnsList.get(i);
				ColumnInfo columnInfo = new ColumnInfo();
				if (null != column.get("columnName")) {
					columnInfo.setColumnName(column.get("columnName")
							.toString());
				} else {
					columnInfo.setColumnName("");
				}

				if (null != column.get("dataType")) {
					columnInfo.setDataType(column.get("dataType").toString());
				} else {
					columnInfo.setDataType("");
				}

				if (null != column.get("columnComment")) {
					columnInfo.setColumnComment(column.get("columnComment")
							.toString());
				} else {
					columnInfo.setColumnComment("");
				}

				columns.add(columnInfo);
			}

			// 生成代码
			generatorCode(table, columns, zip,configBean);
		}

		IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}

	/**
	 * 生成代码
	 */
	public void generatorCode(TableInfo table, List<ColumnInfo> columns,
			ZipOutputStream zip,ConfigBean configBean) {
		// 表名转换成Java属性名
		String className = GenUtils.tableToJava(table.getTableName());
		table.setClassName(className);
		table.setClassname(GenStringUtils.uncapitalize(className));
		// 列信息
		table.setColumns(GenUtils.transColums(columns));
		// 设置主键
		table.setPrimaryKey(table.getColumnsLast());

		VelocityInitializer.initVelocity();

		String moduleName = GenUtils.getModuleName(configBean.getPackageName());

		VelocityContext context = GenUtils.getVelocityContext(table,configBean);

		// 获取模板列表
		List<String> templates = GenUtils.getTemplates();
		for (String template : templates) {
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, "UTF-8");
			tpl.merge(context, sw);
			try {
				// 添加到zip
				zip.putNextEntry(new ZipEntry(GenUtils.getFileName(template,
						table, moduleName)));
				IOUtils.write(sw.toString(), zip, "UTF-8");
				IOUtils.closeQuietly(sw);
				zip.closeEntry();
			} catch (IOException e) {
				throw new BaseException("渲染模板失败，表名：" + table.getTableName(),
						e.getMessage());
			}
		}
	}

}
